Packing
directives. These directives
tell the compiler how to pack the structure members.
This directive can have two forms:
#pragma pack(n)
where n
is 1,2,4,8, or 16. This will align the members of a structure at 1 (i.e., no
packing) at 2, 4, 8, or 16 bytes.
You can also use:
#pragma
pack(push,n)
This will save the current value of the packing
constant, and set it to n, which
should be an integer as explained above. After some code, this allows you to use:
#pragma pack(pop)
to restore the original value again.
Example:
The most common use is at the beginning of an
include file to set the value to a certain amount, and to restore it at the end
of the file.
#pragma pack(push,1)
.....
#pragma pack(pop)
EOF
Include
directives. The pragma
#pragma
once
will ensure that the current file will be read
only once by the compiler. Any further directives for #including the same file
will have no affect.
Optimization
directives. This allows you to
set the optimization flag on or off at certain functions.
#pragma optimize(n)
where n
will be either zero (no optimizations) or one (optimizations).
Switch
generation control. The pragma
#pragma
density(push,0.0)
will trigger the compiler to generate a table
of all possible switch values between the lowest and the highest case statements
found, making a tradeoff that penalizes space for speed. This can of course
overflow if you have:
switch(i) {
case
-10000000:
...
case
10000000:
...
}
In this example, the generated table would have
20 million positions, which may not be a good idea.
On the contrary, in
other cases where the numbers are densely packed, this can be an ideal
optimization.
Including
libraries for the link command
#pragma lib "mylib.lib"
#pragma lib <mylib.lib>
This pragmas allow
you to automatically include a library that is associated with a header file. Paths
enclosed in double quotes will be understood as absolute paths, paths enclosed
in <> will be searched in the standard library paths (normally \lcc\lib).
A stack
frame is an area of storage associated with the activation of a function. A
stack frame that is allocated as a function is entered, and it is deallocated
when the function exits. Automatic (auto)
variables are compiler-generated temporaries that are located in the stack
frame. It is organized as follows:
second parameter |
ESP+8 |
first parameter |
ESP+4 |
caller’s return
address |
ESP+0 |
saved frame pointer |
ESP-4 |
local variables and
temporaries |
ESP-8
ESP -n |
saved registers (if
any) |
|
Usually, it is the EBP
register that points to the stack frame. This register is used to address all
local variables and arguments. When possible, and when the user has specified
the –O (optimization) flag, lcc will not build a full stack frame, but just a
minimal one, consisting only of the saved return address and the registers used
by the procedure.
Lcc-win32 always saves
the registers EBX, EBP, ESI and EDI. Under no circumstances when writing
assembly modules should the values stored in these registers be lost.
A prolog is the code executed immediately upon
a function entry, i.e., the code that builds the stack frame for the function
and saves the registers that the function will use. An epilog is the code executed
to deallocate the stack frame, and restore the saved values of the registers.
The prolog sequence of lcc-win32 is:
push %ebp ;
save the frame pointer
movl %esp,%ebp ;
move the stack pointer to the frame pointer
subl <n>,%esp ; allocate space in the stack for the function’s variables
push %esi ;
save registers
push %edi
push %ebx
Symmetrically, the epilog sequence looks like
this :
pop %ebx ;
restore the saved registers
pop %edi
pop %esi
movl %ebp,%esp ; restore
the stack
popl %ebp ; restore
the old frame pointer
ret ;return to caller. Caller responsible
for cleaning the stack.
Lcc creates the following key in the registry:
HKEY_CURRENT_USER\SOFTWARE\lcc
This key contains the following subkeys:
1. lcc\General General type of information
2. lcc\Compiler Compiler specific information
3. lcc\Wedit For the IDE
4. lcc\lcclnk For the linker
5. lcc\weditres For the resource editor
6. lcc\db Database extension
Following is a description of all keys used by lcc-win32. The prefix
HKEY_CURRENT_USER\Software\lcc
is assumed in all of them.
Key name |
Contents and description
|
SmallEiffel |
Path to the SmallEiffel compiler |
Version |
Version number, for example “2.7” |
compiler\includepath |
Path to the directory included |
lcclnk\libpath |
Path to the libraries |
Wedit |
Project management All the keys following this will have the implicit path: HKEY_CURRENT_USER\Software\lcc\Wedit |
Accel |
Number of user-defined accelerators |
Acceln |
Contents for the nth accelerator |
BackgroundColor |
RGB for the current background color |
CommentColor |
RGB for comment color |
CurrentDir |
Current working directory |
Lcc-win32 defines the following symbols:[1]
Symbol |
Meaning |
__STDC__ |
Defined to 1. This identifies lcc-win32 as an
ANSI C compiler. |
__DATE__ |
Contains the current compilation date in the
format: MMM DD YYY as a character string. |
__TIME__ |
Contains the current time as a character
string in the format: HH:MM:SS Note that this “timer” does not change, even
if the compilation takes a long time. |
__FILE__ |
Contains the name of the current file without
any path component as a character string. |
__func__ |
This symbol will be expanded by the compiler
to a character string containing the name of the current function being
compiled, or the character string “<none>”if no function is currently being defined.[2] |
__LINE__ |
This symbol will be expanded to an integer
containing the current line number in the source file. Note that this line
number can be changed to an arbitrary value with the # line directive. |
__LCC__ |
Allows you to conditionally compile source
for the lcc compiler. |
__LCCOPTIMLEVEL |
If optimization is on, i.e., the –O option
was given in the command line or if the #pragma optimize was parsed, this
preprocessor variable will have the value one. If no optimizations are
active, its value is zero. |
__LCCDEBUGLEVEL |
If the compiler is called with the –g<n> option (debug level n) the value of LCCDEBUGLEVEL is n. If there is no –g in the compiler’s
command line, then its value is zero. |
RC_INVOKED |
Defined by the resource compiler when active. |
WINVER |
Contains a two-byte number with the major
version number of windows in the high byte, and the minor version number in
the low byte. This value is determined at compile time. Note that this
predefined symbol CAN be changed with the #undef directive. |
WIN32 _WIN32 |
Defined to 1. Note that contrary to other
predefined symbols, this symbol can be undefined with the #undef directive. |
__int64 |
Defined as the long long integer type for compatibility with the Microsoft compiler. |
__cdecl __inline _cdecl _huge |
Defined to the empty string for compatibility
reasons. |
Symbol |
Meaning |
_asm(“ “); |
In-line assembly instruction(s). |
_stdcall |
Call convention declaring a function that
cleans up the stack before executing the return statement. |
_try |
Introduces a try block in the Win32
structured exception handling. |
_except |
Finishes a structured try block. |
__declspec |
Declare special. Its arguments can be: __declspec(dllimport) meaning the symbol following this declaration
is imported from a foreign DLL, or: __declspec(dllexport) meaning this symbol should be exported from
the DLL being compiled. |
[1] Note
that none of this identifiers can be undefined with the #undef macro directive.
[2] The standard gives the following definition for this:
“The identifier _ _func_ _ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration static const char _ _func_ _[]="function-name"; appeared, where function-name is the name of the lexically-enclosing function.”.
WG14/N843 ANSI standard page 45. Note that the behavior of lcc-win32 is more lenient: the symbol still has a valid value outside a function.